#include "network.h"
#include <iostream>
#include <iomanip>
#include "logmanager.h"
#include <sstream>


using namespace std;

Network::Network()
: threadRunning(false), port(port)
{
	readyPackages = new std::queue<PacketWithSource*>(); // This throws a linker warning, what to do?
}

Network::~Network()
{
	threadRunning = false;
	Wait();
	socket.Close();
	delete readyPackages;
}

bool Network::StartUDPListening(unsigned short port)
{
	if (socket.Bind(port))
	{
		Launch();
		return true;
	}
	return false;
}

std::queue<PacketWithSource*>* Network::GetReadyPackages()
{
	sf::Lock Lock(queueMutex);
	if (!readyPackages->empty())
	{
		std::queue<PacketWithSource*>* x = readyPackages;
		readyPackages = new std::queue<PacketWithSource*>();

		return x;
	}
	return NULL;
}

void Network::Send(sf::Packet& d, sf::IPAddress& a, unsigned short p)
{
	socket.Send(d, a, p);
}

void Network::PutPackageOnReadyQueue(sf::SocketUDP& thisSocket)
{
	sf::Lock Lock(queueMutex);

	sf::Packet data;
	sf::IPAddress sender;
	unsigned short port;
	thisSocket.Receive(data, sender, port);

	readyPackages->push(new PacketWithSource(data, sender, port));
}

void Network::Run()
{
	sf::SelectorUDP selector;
	selector.Add(socket);

	threadRunning = true;
	while(threadRunning)
	{
		unsigned int numSockets = selector.Wait(0.001f);
		for (unsigned int s=0;s<numSockets;++s)
		{
			sf::SocketUDP thisSocket = selector.GetSocketReady(s);
			PutPackageOnReadyQueue(thisSocket);
		}
	}
}

